﻿/*
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * See product pages for more information.
 * http://closesudoku.codeplex.com
 * Copyright (C), 2010, hrondra
 */
using System;
using System.Collections.Generic;
using System.Text;
using Fluid.Controls;
using System.Windows.Forms;
using System.Drawing;
using Close.Classes;
using Close.Properties;
using Close.controls.FFluid;

namespace Close.controls.GamePads
{
    class Popup : FluidPanel
    {
        //TODO: set it dynamically
        Color buttonNumericBackGround = Color.Black;
        Color buttonNumericBackGroundSelected = Color.Blue;
        Color tabBackGroundActive = Color.SlateGray;
        Color tabBackGroundInactive = Color.LightGray;
        Color tabForeActive = Color.Black;
        Color tabForeInactive = Color.Gray;
        const int minGap = 1;
        //----------------------------------------------------------------------

        readonly string[] commands = new string[] {
            "1", "2", "3", "4", "5", "6", "7", "8", "9"};

        public static readonly string commandExit = "exit";
        ThemeClass themeClass = ThemeClass.Settings;

        public Popup(int x, int y, int w, int h)
            : base(x, y, w, h)
        {

        }

        private FlatButton btnNumber = new FlatButton("Number");
        private FlatButton btnNote = new FlatButton("Note");


        protected override void InitControl()
        {
            base.InitControl();
            EnableDoubleBuffer = false;
            this.BackColor = tabBackGroundActive;

            int rowColBetweenGap = ((this.Width) % 9) > minGap ? ((this.Width) % 9) / 2 : minGap;
            int buttonNumericWidth = (this.Width) / 3 - rowColBetweenGap;
            int verticalFrameHeight = (int)(.15 * this.Height);

            int buttonNumericHeight = (int)(.7 * this.Height / 3 - rowColBetweenGap);

            //Upper
            ButtonGroup tab = new ButtonGroup(rowColBetweenGap, rowColBetweenGap, this.Width - 2 * rowColBetweenGap, verticalFrameHeight - rowColBetweenGap);
            
            btnNumber.BackColor = tabBackGroundInactive;
            btnNumber.PressedBackColor = tabBackGroundActive;
            btnNumber.ForeColor = tabForeInactive;
            btnNumber.PressedForeColor = tabForeActive;            
            btnNumber.Click += new EventHandler(btnTabulator_Click);
            btnNumber.IsSticky = true;
            btnNumber.EnableCache = false;
            tab.Add(btnNumber);

            btnNote.BackColor = tabBackGroundInactive;
            btnNote.PressedBackColor = tabBackGroundActive;
            btnNote.ForeColor = tabForeInactive;
            btnNote.PressedForeColor = tabForeActive;
            btnNote.Click += new EventHandler(btnTabulator_Click);
            btnNote.IsSticky = true;
            btnNote.EnableCache = false;
            tab.Add(btnNote);

            ((FluidControlCollection)GetControls()).Add(tab);

            //Middle
            for (int row = 0; row < 3; row++)
			{
                for (int column = 0; column < 3; column++)
			    {
                    FluidButton btn = new FluidButton(commands[row * 3 + column], buttonNumericWidth * column + rowColBetweenGap * column, verticalFrameHeight + buttonNumericHeight * row + 2 * rowColBetweenGap + rowColBetweenGap * row, buttonNumericWidth, buttonNumericHeight);
                    btn.Name = "popupButton" + (row * 3 + column + 1).ToString();
                    btn.BackColor = buttonNumericBackGround;
                    btn.PressedBackColor = buttonNumericBackGroundSelected;
                    btn.ForeColor = Fluid.Classes.Theme.ThemeClass.Settings.NumpadForeColor;
                    btn.Command = (row * 3 + column + 1).ToString();

                    btn.PaintButtonText += new EventHandler<FluidPaintEventArgs>(btn_PaintButtonText);
                    btn.Click += new EventHandler(btn_Click);

                    ((FluidControlCollection)GetControls()).Add(btn);
			    }
			}

            //Botton
            //ButtonGroup tabBellow = new ButtonGroup(rowColBetweenGap, verticalFrameHeight + (buttonNumericHeight  + rowColBetweenGap) * 3  + 3 * rowColBetweenGap, this.Width - 2 * rowColBetweenGap, verticalFrameHeight - rowColBetweenGap - 4 * rowColBetweenGap);

            FluidButton btnExit = new FluidButton(Resources.PopupClose);
            btnExit.Bounds = new Rectangle(rowColBetweenGap, verticalFrameHeight + (buttonNumericHeight + rowColBetweenGap) * 3 + 3 * rowColBetweenGap, (this.Width - 2 * rowColBetweenGap) / 2, verticalFrameHeight - rowColBetweenGap - 4 * rowColBetweenGap);
            btnExit.Command = commandExit;
            btnExit.Click += new EventHandler(btn_Click);
            btnExit.BackColor = buttonNumericBackGround;
            btnExit.ForeColor = Fluid.Classes.Theme.ThemeClass.Settings.NumpadForeColor;
            Controls.Add(btnExit);

            FluidButton btnClear = new FluidButton(Resources.PopupClear);
            btnClear.Bounds = new Rectangle(rowColBetweenGap + (this.Width - 2 * rowColBetweenGap) / 2, verticalFrameHeight + (buttonNumericHeight + rowColBetweenGap) * 3 + 3 * rowColBetweenGap, (this.Width - 2 * rowColBetweenGap) / 2, verticalFrameHeight - rowColBetweenGap - 4 * rowColBetweenGap);
            btnClear.Command = "C";
            btnClear.ForeColor = Fluid.Classes.Theme.ThemeClass.Settings.NumpadForeColor;
            btnClear.BackColor = buttonNumericBackGround;
            btnClear.Click += new EventHandler(btn_Click);
            Controls.Add(btnClear);

            //tabBellow.Add(btnExit);
            //tabBellow.Add(btnClear);
            //((FluidControlCollection)GetControls()).Add(tabBellow);
        }

        /// <summary>
        /// Change numbers/notes tab.
        /// </summary>
        private void btnTabulator_Click(object sender, EventArgs e)
        {
            if (sender == btnNumber)
            {
                btnNote.SetIsDownFalse();
                btnNumber.SetIsDownTrue();

                ResetButtons(false);
                PresetValue(_gridButton.FaceValue);
            }
            else if (sender == btnNote)
            {
                btnNumber.SetIsDownFalse();
                btnNote.SetIsDownTrue();

                ResetButtons(true);
                PresetNotes(_gridButton.AllNotes);
            }
        }

        public delegate void PopupButtonDelegate(Popup sender, FluidButton button);
        
        /// <summary>
        /// Button exit clicked.
        /// </summary>        
        public event PopupButtonDelegate ButtonClick;

        void btn_Click(object sender, EventArgs e)
        {
            FluidButton btn = (FluidButton)sender;


            if (btn.Command.Length == 1)
            {
                char btnValue = btn.Command[0];
                if (btnNumber.IsDown)
                {
                    if (btnValue == 'C')
                        _gridButton.FaceValue = ' ';
                    else
                        _gridButton.FaceValue = btnValue; 
                }
                else
                {
                    if (btnValue == 'C')
                        _gridButton.SetNote(0);
                    else
                    _gridButton.SetNote((byte)btnValue - '0');
                }
            }
            if (ButtonClick != null)
                ButtonClick(this, btn);
            
        }

        void btn_PaintButtonText(object sender, FluidPaintEventArgs e)
        {
            FluidButton btn = (FluidButton)sender;
            Font smallFont = new Font(FontFamily.GenericSansSerif, 10f, FontStyle.Bold);
            StringFormat stringFormat = new StringFormat(StringFormatFlags.NoWrap);

            string text = btn.Text;
            Graphics g = e.Graphics;
            Rectangle rect = e.ControlBounds;

            if (btn.Image != null)
            {
                int imW = ScaleX(btn.Image.Width);
                int imH = ScaleY(btn.Image.Height);

                int w = Math.Min(imW, rect.Width);
                int h = Math.Min(imH, rect.Height);
                rect.Width = w - 5;
                rect.Height = h - 5;
                rect.X += 2;
                rect.Y += 2;

                if (btn.IsDown)
                {
                    rect.X++;
                    rect.Y++;
                }

                System.Drawing.Imaging.ImageAttributes attr = new System.Drawing.Imaging.ImageAttributes();
                //pruhledna
                attr.SetColorKey(Color.Fuchsia, Color.Fuchsia);

                g.DrawImage(btn.Image, rect, 0, 0, btn.Image.Width, btn.Image.Height, GraphicsUnit.Pixel, attr);
            }

            if (text.Length > 0)
            {
                Brush brush;
                if (btn.IsDown && btn.PressedForeColor != Color.Empty)
                    brush = new SolidBrush(btn.PressedForeColor);                
                else
                    brush = new SolidBrush(btn.ForeColor);                
                
                float smallWidth = e.ScaleFactor.Width * 5f + g.MeasureString(btn.Text, smallFont).Width;
                int dw = (int)((btn.Width - smallWidth) / 2f);
                int dh = (int)(2f * e.ScaleFactor.Width);
                RectangleF rf = RectFFromRect(rect);
                //stringFormat.LineAlignment = StringAlignment.Far;
                stringFormat.LineAlignment = StringAlignment.Center;
                stringFormat.Alignment = StringAlignment.Center;
                g.DrawString(btn.Text, smallFont, brush, rf, stringFormat);
            }

        }
        private GridButton _gridButton;

        /// <summary>
        /// Field in gameboard.
        /// </summary>
        public GridButton ButtonInGrid
        {
            get
            {
                return _gridButton;
            }
        }

        /// <summary>value when showed</summary>
        private char _originalValue;
        /// <summary>value when showed</summary>
        private string _originalNotes;
        public void Show(GridButton btn)
        {
            _gridButton = btn;
            _originalValue = btn.FaceValue;
            _originalNotes = btn.AllNotes;
            if (_gridButton.FaceValue != ' ')
            {
                btnTabulator_Click(btnNumber, null);
            }
            else if (!string.IsNullOrEmpty(_gridButton.AllNotes))
            {
                btnTabulator_Click(btnNote, null);
            }
            else
                btnTabulator_Click(btnNumber, null);
            base.Show();            
        }

        public bool wasChanged
        {
            get { return !(_originalValue == _gridButton.FaceValue && _originalNotes == _gridButton.AllNotes); }
        }

        /// <summary>
        /// Select value in popup.
        /// </summary>
        /// <param name="value">1 - 9</param>
        private void PresetValue(char value)
        {
            foreach (FluidControl flc in this.GetControls())
            {
                if (!String.IsNullOrEmpty(flc.Name))
                {
                    if (flc.Name == "popupButton" + value)
                    {
                        FluidButton btn2 = (FluidButton)flc;
                        btn2.SetIsDownTrue();
                    }
                }
            }
        }

        /// <summary>
        /// Select all notes in popup.
        /// </summary>
        /// <param name="notes">notes separated by spaces</param>
        private void PresetNotes(string notes)
        {
            string[] note = notes.Split(' ');
            foreach (FluidControl flc in this.GetControls())
            {
                if (!String.IsNullOrEmpty(flc.Name))
                {
                    foreach (string str in note)
                    {
                        if (flc.Name == "popupButton" + str)
                        {
                            FluidButton btn2 = (FluidButton)flc;
                            btn2.SetIsDownTrue();
                            continue;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Uncheck all buttons.
        /// </summary>
        private void ResetButtons(bool sticky)
        {
            foreach (FluidControl flc in this.GetControls())
            {
                if (!String.IsNullOrEmpty(flc.Name))
                {
                    if (flc.Name.IndexOf("popupButton") >= 0)
                    {
                        FluidButton btn2 = (FluidButton)flc;
                        btn2.IsSticky = sticky;
                        btn2.SetIsDownFalse();
                    }
                }
            }
        }

    }
}
